home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / Developer Essentials Jul 90 / Programming / MPW Interfaces & Libraries 3.1 / AStructMacs / Sample.a < prev    next >
Encoding:
Text File  |  1988-11-30  |  16.7 KB  |  455 lines  |  [TEXT/MPS ]

  1.                 TITLE            'Sample - A small sample application using Structured Macros'
  2.                 
  3. * File Sample.a using structured program macros
  4. * Copyright Apple Computer, Inc. 1985, 1986, 1987
  5. * All rights reserved.
  6.  
  7. * Sample -- A small sample application written in MPW Assembler.  It displays
  8. * single, fixed-size window in which the user can enter and edit text.
  9.  
  10. * This is a translation of the Sample.a program in AEXamples, which in turn is
  11. * a translation of the Pascal version of Sample shown in the Inside Macintosh
  12. * documentaion.  Some changes were made to illustrate some of the features of
  13. * the MPW Assembler, but most comments and the order of the code is the same as
  14. * the Pascal example.  Since this Sample.a is a translation of the AExamples
  15. * Sample.a, you may substitute this file for AExamples:Sample.a and use the
  16. * AExamples make file to assemble and line the sample program.
  17.  
  18. * Note, this code assumes that the DEGUG switch available to the structured
  19. * macros is OFF (the preset case), since DoCommand pops its return and
  20. * parameter directly off the stack and doesn't know that with DEBUG set a
  21. * LINK on A6 is generated!
  22.  
  23. * The PRINT directive turns off listing (if a listing is being generated using
  24. * -l command line option) of the standard include files.  The INCLUDEs bring in
  25. * the equate and trap definitions needed by Sample.  We could use the LOAD/DUMP
  26. * facilities on these includes if we intended to assemble this program over and
  27. * over again, but that would confuse the example here.
  28.  
  29.                 PRINT            OFF
  30.                 INCLUDE     'Traps.a'
  31.                 INCLUDE     'ToolEqu.a'
  32.                 INCLUDE     'QuickEqu.a'
  33.                 INCLUDE     'SysEqu.a'
  34.                 LOAD            'ProgStrucMacs.d'
  35.                 LOAD            'FlowCtlMacs.d'
  36.                 PRINT            ON,NOGEN
  37.  
  38.  
  39.                 TITLE            'Global Declarations for Sample'
  40.  
  41. *************
  42. * Constants *
  43. *************
  44.  
  45. appleID             EQU             128         ; Resource IDs/menu IDs for Apple,
  46. fileID                EQU             129         ;     File, and Edit menus
  47. editID                EQU             130
  48.  
  49. menuCount            EQU             3                ; Total number of menus
  50.  
  51. windowID            EQU             128         ; Resource ID for application'w window
  52.  
  53. undoCommand     EQU             1                ; Menu item numbers identifying
  54. cutCommand        EQU             3                ; commands in Edit menu
  55. copyCommand     EQU             4
  56. pasteCommand    EQU             5
  57. clearCommand    EQU             6
  58.  
  59. aboutMeDLOG     EQU             128         ; Resource ID for the "about" dialog
  60.  
  61. authorItem        EQU             2                ; "About sample" dialog item numbers
  62. languageItem    EQU             3
  63.  
  64.  
  65. *********
  66. * Types *
  67. *********
  68.  
  69. * To illustrate how the template type feature works the following templates are
  70. * declared and used instead of the simple offsets defined in the equate files.
  71. * By using these, the Assember source appromixates very closely the Pascal
  72. * source for referencing the corresponding information.  Perhaps someday we will
  73. * have a set of "equate" files that define types just like Pascal USES units do!
  74.  
  75. Point                    RECORD        0                ; Point = RECORD CASE INTEGER OF
  76. v                            DS.W            1                ;                  1: (v: INTEGER;
  77. h                            DS.W            1                ;                            h: INTEGER);
  78.                             ORG             v                ;                    2: (vh: ARRAY[1..2] OF INTEGER)
  79. vh                        DS.L            1
  80.                             ENDR                            ;                    END;
  81.  
  82. Rect                    RECORD        0                ; Rect  = RECORD CASE INTEGER OF
  83. top                     DS.W            1                ;                    1: (top:    INTEGER;
  84. left                    DS.W            1                ;                            left:   INTEGER;
  85. bottom                DS.W            1                ;                            bottom: INTEGER;
  86. right                    DS.W            1                ;                            right:  INTEGER);
  87.                             ORG             top            ;
  88. topLeft             DS.L            Point        ;                    2: (topLeft:  Point;
  89. botRight            DS.L            Point        ;                    3: (botRight: Point)
  90.                             ENDR                            ;                  END;
  91.  
  92. BitMap                RECORD        0                ;  BitMap = RECORD
  93. baseAddr            DS.L            1                ;                      baseAddr: QDPtr;
  94. rowBytes            DS.W            1                ;                      rowBytes: INTEGER;
  95. bounds                DS.L            Rect        ;                          bounds:    Rect
  96.                             ENDR                            ;                    END;
  97.  
  98. EventRecord     RECORD        0                ; EventRecord = RECORD
  99. what                    DS.W            1                ;                          what:      INTEGER;
  100. message             DS.L            1                ;                          message:     LONGINT;
  101. when                    DS.L            1                ;                          when:      LONGINT;
  102. where                    DS.L            Point        ;                          where:         Point;
  103. modifiers            DS.W            1                ;                          modifiers: INTEGER
  104.                             ENDR                            ;                        END;
  105.  
  106.                 EJECT
  107.  
  108. ***********************
  109. * QuickDraw's Globals *
  110. ***********************
  111.  
  112. * The following data module is used to define the QuickDraw global data area.
  113. *                -----------
  114.  
  115. QuickDraw            RECORD        ,DECREMENT
  116. thePort             DS.L            1
  117. white                    DS.B            8
  118. black                    DS.B            8
  119. gray                    DS.B            8
  120. ltGray                DS.B            8
  121. dkGray                DS.B            8
  122. arrow                    DS.B            cursRec
  123. screenBits        DS.B            BitMap
  124. randSeed            DS.L            1
  125.                             ORG             -grafSize
  126.                             ENDR
  127.  
  128.  
  129. **************************
  130. * Global Data for Sample *
  131. **************************
  132.  
  133. * This is the global data used by Sample.  Both these and the QuickDraw data
  134. * above are referenced through a WITH statetment at the beginning of the procs
  135. * that use this data. Since the Assembler knows when it is referencing data
  136. * in a data module (since they must be declared before they are accessed),
  137. * and since such data can only be accessed based on A5, there is no need to
  138. * explicitly specify A5 in any code which references the data (unless indexing
  139. * is used).  Thus, in this program we have omitted all A5 references when
  140. * referencing the data.
  141.  
  142. GlobalData        RECORD
  143. appleMenuH        DS.L            1                            ; Handle to the Apple menu
  144. fileMenuH            DS.L            1                            ; Handle to the File menu
  145. editMenuH            DS.L            1                            ; Handle to the Edit menu
  146. dragRect            DS.L            Rect                    ; Drag limits
  147. txRect                DS.L            Rect                    ; TextEdit's limits
  148. doneFlag            DS.B            1                            ; True if Quit command processed
  149. myEvent             DS.L            EventRecord     ; Current event info
  150. wRecord             DS.B            windowSize        ; The application window record
  151. myWindow            DS.L            1                            ; Ptr to the application window
  152. whichWindow     DS.L            1                            ; Current event's window
  153. textH                    DS.L            1                            ; TextEdit's text handle
  154. mousePt             DS.L            Point                    ; Used to get current mouse point
  155. iBeamHdl            DS.L            1                            ; Handle to the iBeam cursor
  156.                             ENDR
  157.  
  158.  
  159.                 TITLE            'SetupMenus - Set up menus and menu bar'
  160.  
  161. ******************************************
  162. * SetUpMenus - Set up menus and menu bar *
  163. ******************************************
  164.  
  165. * This is a code module used only during initialization.  Note, just as in the
  166. * Pascal version, this is a distinct code module.  Also, since SetUpMenus is
  167. * only called during initialization, there is no need to keep it loaded.  So
  168. * we will place SetUpMenus in its own segment (called "Initialize") and unload
  169. * it after SetUpMenus returns.
  170.  
  171.     SEG  'Init'                                                ; This illustrates segmenting!
  172.   PROCEDURE SetUpMenus
  173.             
  174.         BEGIN With=GlobalData
  175.             Call _GetRMenu:L(#appleID),(Pass,appleMenuH); Read Apple menu from rsrc file
  176.             Call _InsertMenu((A7):L, #0)    ; Install Apple menu in menu bar
  177.             Call _AddResMenu(, #'DRVR':L)    ; Add DA names to Apple menu
  178.             
  179.             Call _GetRMenu:L(#fileID),(Pass,fileMenuH); Read File menu from rsrc file
  180.             Call _InsertMenu(, #0)                ; Install File menu in menu bar
  181.             
  182.             Call _GetRMenu:L(#editID),(Pass,editMenuH); Read Edit menu from rsrc file
  183.             Call _InsertMenu(, #0)                ; Install Edit menu in menu bar
  184.             
  185.             Call _DrawMenuBar                            ; Draw the menu bar
  186.             Return                                                ; Exit
  187.         ENDP
  188.  
  189.  
  190.                 TITLE            'ShowAboutMeDialog - Display the "About"...'
  191.  
  192. **********************************************
  193. * ShowAboutMeDialog - Display the "About"... *
  194. **********************************************
  195.  
  196. * This procedure is called from DoCommand when item #1 is selected from the
  197. * apple menu list.    It sets up a dialog box indicating the author and language
  198. * of this sample program.  The box remains until the user clicks the mouse on
  199. * the continue button.
  200.  
  201.     SEG                                                             ; Undo SEG done above
  202.     PROCEDURE ShowAboutMeDialog
  203.                 
  204.         VAR savePort: L,                          \    ; Port at the time of call
  205.                 itemType: W,                          \    ; Returned by _GetDItem (not used)
  206.                 itemHdl:  L,                            \    ; Handle to the item
  207.                 itemRect: Rect,                      \    ; Returned by _GetDItem (not used)
  208.                 itemHit:  W                                ; Part code
  209.                 
  210.         BEGIN Save=A3
  211.           theDialog: EQU A3                            ; Dialog pointer
  212. *
  213. *         Start here: create  current grafPort, and allocate space for the dialog box
  214. *
  215.             Call _GetPort(savePort(FP):A)    ; Remember the current grafPort
  216.             Call _GetNewDialog:A(#aboutMeDLOG, NIL, -1:A)    ;Create a new dialog
  217.             MOVE.L    (A7),theDialog                ; theDialog holds ptr to dialog info
  218.             Call _SetPort                                    ; Set the current grafPort
  219. *
  220. *         Fill in the dialog box with the proper author and language
  221. *
  222.             Call _GetDItem(theDialog:L, #authorItem, itemType(FP):A, itemHdl(FP):A, \
  223.                                         itemRect(FP):A); Get dialog's author item info
  224.             Call _SetIText(itemHdl(FP):L, #'Nebur L. Ari':A); Update the author item
  225.             
  226.             Call _GetDItem(theDialog:L, #languageItem, itemType(FP):A, itemHdl(FP):A, \
  227.                                         itemRect(FP):A); Get dialog's language info
  228.             Call _SetIText(itemHdl(FP):L, #'Assembler':A); Update the language item
  229. *
  230. *         Wait for user to click the continue button
  231. *
  232.             REPEAT#    
  233.                 Call _ModalDialog(NIL, itemHit(FP):A)    ; Wait for the click...
  234.             UNTIL#.S itemHit(FP) EQ #okButton
  235. *
  236. *         User is now satisfied -- let's get out of here!
  237. *
  238.             Call _CloseDialog(theDialog:L); Close the dialog box
  239.             Call _SetPort(savePort(FP):L)    ; Put original grafPort back
  240.             Return
  241.         ENDP
  242.  
  243.  
  244.                 TITLE            'DoCommand - Execute a menu command'
  245.  
  246. ***********************************************************************
  247. * DoCommand - Execute command specified by the result of a MenuSelect *
  248. ***********************************************************************
  249.  
  250. * This is another code module which takes as a parameter the MenuSelect return
  251. * value.  It is next to the top of the stack just before the return address.
  252.  
  253.     PROCEDURE DoCommand;
  254.     
  255.         BEGIN With=GlobalData
  256.             return:  EQU A6                                ; The return address will be in A6
  257.             mResult: EQU D3                                ; mResult will be kept in D3
  258.             theItem: EQU mResult                     ; LoWord(mResult) is mResult treated as a word
  259.  
  260. *         The following defines some local data known only to this proc.
  261.  
  262.             DATA                                                    ; Switch into local data section
  263.             name: DS.B    256                             ; Desk accessory name string
  264.             CODE                                                    ; Switch back to code section
  265.  
  266.             MOVEA.L    (A7)+,return                    ; Pop return into A6
  267.             MOVE.L    (A7)+,mResult                    ; Pop mResult parameter
  268.             
  269.             MOVE.L    mResult,D0                        ; Case on menu ID in
  270.             SWAP        D0                                        ;    high-order word of mResult
  271.  
  272.             Switch#    D0
  273.                 Case#.S appleID                            ; Apple menu processing
  274.                     Call _GetItem(appleMenuH:L, theItem, name:A); Get DA name
  275.                     IF# theItem EQ #1 THEN.S
  276.                         Call ShowAboutMeDialog
  277.                     ELSE#.S
  278.                         Call _OpenDeskAcc:W(name:A),Pop
  279.                     ENDIF#
  280.                     Call _SetPort(myWindow:L); Restore app window as grafPort
  281.                     Leave#.S                                ;  Exit
  282.  
  283.                 Case#.S fileID                        ; File menu processing
  284.                     ST doneFlag                            ; Set flag to Quit (caller tests)
  285.                     Leave#.S                                ; Exit
  286.  
  287.                 Case#.S editID                        ; Edit menu processing
  288.                     MOVE theItem,D1                    ; if DA window is the active window
  289.                     SUBQ #1,D1                            ; SystemEdit requires item adjustment
  290.                     Call _SysEdit:B(D1),CC    ; Call Desk Mgr to handle editing command
  291.                                                                     ; if DA window is the active window
  292.                     IF# EQ THEN.S                        ; App window is active window
  293.                         Switch# theItem                ; Case on menu item (command) number
  294.                             Case#.S cutCommand; Call TextEdit to handle command
  295.                                 Call _TECut(textH:L)
  296.                                 Leave#.S
  297.                             Case#.S copyCommand
  298.                                 Call _TECopy(textH:L)
  299.                                 Leave#.S
  300.                             Case#.S pasteCommand
  301.                                 Call _TEPaste(textH:L)
  302.                                 Leave#.S
  303.                             Case#.S clearCommand
  304.                                 Call _TEDelete(textH:L)
  305.                         EndS#                                ; of item case
  306.                     ENDIF#
  307.             EndS#                                            ; of editID case
  308.                 
  309.             Call _HiliteMenu(#0)            ; Unhighlight menu item
  310.             JMP (return)                            ; Exit
  311.         ENDP
  312.  
  313.                  TITLE            'Sample - Main Program'
  314.  
  315. ***********************************************
  316. * Sample Main Program - Execution starts here *
  317. ***********************************************
  318.  
  319. * This is another code module.    It is declared as the main code module which
  320. * means execution will start here.
  321.  
  322.     PROCEDURE Sample,Main=Y
  323.         
  324.         BEGIN With=(QuickDraw,GlobalData)    ;  Cover our data areas
  325. *
  326. *         Initialization
  327. *
  328.             Call _InitGraf(thePort:A)    ; Initialize QuickDraw
  329.             Call _InitFonts                        ; Initialize Font Manager
  330.             MOVE.L    #$0000FFFF,D0            ; Discard any previous events
  331.             Call _FlushEvents                    ; FlushEvents(EventEvent, 0);
  332.             Call _InitWindows                    ; Initialize Window Manager
  333.             Call _InitMenus                        ; Initialize Menu Manager
  334.             Call _TEInit                             ; Initialize TextEdit
  335.             Call _InitDialogs(NIL)        ; Initialize Dialog Manager
  336.             Call _InitCursor                     ; Make cursor an arrow
  337.             
  338.             Call _GetCursor:L(#iBeamCursor),iBeamHdl; Get the iBeam cursor handle to
  339.                                                                                             ; use in the main ctl loop when
  340.                                                                                             ; cursor is in the window
  341.  
  342.             Call SetUpMenus                        ; Set up menus and menu bar
  343.             Call _UnLoadSeg(SetUpMenus:A)    ; Unload the SetUpMenus segment since we
  344.                                                                         ; will never call it again
  345.             
  346.             WITH    screenBits.bounds            
  347.             MOVE       right,D0                    ; Call QuickDraw to set dragging
  348.             SUBQ      #4,D0                            ; boundaries; ensure at least
  349.             MOVE      bottom,D1                    ; 4 by 4 pixels will remain visible
  350.             SUBQ      #4,D1
  351.             Call _SetRect(dragRect:A, #4, #24, D0, D1)
  352.             ENDWITH
  353.             
  354.             CLR.B        doneFlag                    ; Flag to detect Quit command
  355.             
  356.             Call _GetNewWindow:L(#windowID, wRecord:A, #-1:L),(Pass,myWindow); Put up app window
  357.             Call _SetPort()                        ; Set current grafPort to this window
  358.             MOVE.L    thePort,A0                ; Rectangle for text in window
  359.             MOVE.L    portRect+topLeft(A0),txRect.topLeft
  360.             MOVE.L    portRect+botRight(A0),txRect.botRight
  361.             Call _InSetRect(txRect:A, #4, #0)                ; Bring it in 4 pixels from left/right edges
  362.             Call _TENew:L(txRect:A, txRect:A),textH    ; Prepare for receiving text
  363.  
  364.                 EJECT
  365. *
  366. *         Main Event Loop
  367. *
  368.             REPEAT# 
  369.                 Call _SystemTask                     ; Perform periodic actions defined for DAs
  370.  
  371.                 Call _FrontWindow:L,D0        ; Get ptr to the front window
  372.                 IF# D0 EQ.L myWindow THEN.S    ; Front window is my mindow
  373.                     Call _GetMouse(mousePt:A); Is mouse pointing in my window ?
  374.                     MOVEA.L     myWindow,A0
  375.                     Call _PtInRect:B(mousePt:L, portRect(A0):A),CC
  376.                     IF# NE THEN.S                        ; Yes, use the iBeam cursor
  377.                         MOVE.L    iBeamHdl,A0
  378.                         MOVE.L    (A0),-(A7)
  379.                     ELSE#.S                                    ; No, use the arrow cursor
  380.                         PEA     arrow
  381.                     ENDIF#
  382.                     Call _SetCursor                    ; Set cursor to arrow or iBeam
  383.                     Call _TEIdle(textH:L)        ; Make vertical bar blink
  384.                 ENDIF#
  385.  
  386.                 Call _GetNextEvent:B(#everyEvent, myEvent:A),CC; ToolBox Event Mgr
  387.                 IF# NE THEN
  388.                     Switch# myEvent.what,JmpTbl=Y,ChkRng=Y; Case on event type
  389.                         Case# mButDwnEvt            ; Mouse down event processing
  390.                             Call _FindWindow:W(myEvent.where:L, whichWindow:A),D0
  391.                             Switch# D0                    ; Process according to where
  392.                                 Case#.S inMenuBar    ; Menu bar: process command
  393.                                     Call _MenuSelect:L(myEvent.where:L)
  394.                                     Call DoCommand    ; DoCommand(MenuSelect(myEvent.where));
  395.                                     Leave#.S
  396.                                 
  397.                                 Case#.S inSysWindow    ; Desk accessory window
  398.                                     Call _SystemClick(myEvent:A, whichWindow:L)
  399.                                     Leave#.S
  400.                                     
  401.                                 Case#.S inDrag        ; Title bar
  402.                                     Call _DragWindow(whichWindow:L, myEvent.where:L, dragRect:A)
  403.                                     Leave#.S
  404.                                     
  405.                                 Case#.S inContent    ; Body of application window
  406.                                     Call _FrontWindow:L,D0                 ; Which is in front?
  407.                                     IF# D0 NE.L whichWindow THEN.S    ; Not us!
  408.                                         Call _SelectWindow(whichWindow:L)
  409.                                     ELSE#.S                                                ; If we are in front...
  410.                                         Call _GlobalToLocal(myEvent.where:A)
  411.                                         MOVE.L    myEvent.where,-(A7)   
  412.                                         MOVE        myEvent.modifiers,D0
  413.                                         BTST        #shiftKey,D0
  414.                                         SNE         -(A7)                                ; Indicate if shift key is down
  415.                                         Call _TEClick(,,textH:L)
  416.                                     ENDIF#
  417.                             EndS#
  418.                             Leave#
  419.                         
  420.                         Case# keyDwnEvt,autoKeyEvt    ; Key down and Auto key event processing
  421.                             BTST        #CmdKey,myEvent.modifiers
  422.                             IF# NE THEN.S                ; If cmd key down, call Menu Mgr to learn which
  423.                                 Call _MenuKey:L(myEvent.message+2)
  424.                                 Call DoCommand        ; Process the command key
  425.                             ELSE#.S                            ; If not a command key...
  426.                                 Call _TEKey(myEvent.message+2, textH:L); ...pass char to TE
  427.                             ENDIF#
  428.                             Leave#.S
  429.                         
  430.                         Case# activateEvt            ; Activate/deactivate event processing
  431.                             MOVE        myEvent.modifiers,D0; App window status changed
  432.                             BTST        #activeFlag,D0            ; Is app window becoming active ?
  433.                             IF# NE THEN.S                                ; Yes
  434.                                 Call _TEActivate(textH:L)    ; Call TE to highlight selection and
  435.                                 Call _DisableItem(editMenuH:L, #undoCommand); disable UnDo
  436.                             ELSE#.S                                            ; App window is becoming inactive
  437.                                 Call _TEDeactivate(textH:L); Unhighlight selection and
  438.                                 Call _EnableItem(editMenuH:L, #undoCommand); enable UnDo
  439.                             ENDIF#
  440.                             Leave#.S
  441.                             
  442.                         Case# updatEvt                ; Update event processing
  443.                             Call _BeginUpDate(myEvent.message:L)        ; Window needs updating
  444.                             MOVEA.L    thePort,A3                                            ; We need thePort^.portRect
  445.                             Call _EraseRect(portRect(A3):A)                    ; Call QD to erase text area
  446.                             Call _TEUpdate(portRect(A3):A, textH:L)    ; Call TE to update the text
  447.                             Call _EndUpDate(myEvent.message:L)            ; End update
  448.                     ENDS#
  449.                 ENDIF#
  450.                     
  451.                 TST.B    doneFlag
  452.             UNTIL# NE
  453.             Return
  454.         END                                                                 ; of Sample
  455.